<script>
import {mapGetters, mapState} from "vuex";
import dayjs from "dayjs";
import {hireType} from "@/constant/employees";
import EmpFormDialog from "@/views/employees/components/empFormDialog.vue";
import UploadExcelDialog from "@/views/employees/components/uploadExcelDialog.vue";
import RoleDialog from "@/views/employees/components/roleDialog.vue";

export default {
  name: "employees",
  components: {RoleDialog, UploadExcelDialog, EmpFormDialog},
  data() {
    return {
      /* 分页的参数 */
      pageParams: {page: 1, size: 10},
      /* 是否显示添加员工的对话框 */
      showEmpDialog: false,
      /* 是否显示导入excel的对话框 */
      showUploadDialog: false,
      /* 是否显示角色对话框 */
      showRoleDialog: false
    }
  },
  methods: {
    /* 格式化时间的回调函数 */
    formatData(date) {
      return dayjs(date).format('YYYY年MM月DD日')
    },
    /* fetchEmployees()函数用于派发action发送请求获取员工列表  */
    async fetchEmployees() {
      try {
        await this.$store.dispatch('employeesStore/fetchEmployees', this.pageParams)
      } catch (error) {
        this.$message.error(error.message)
      }
    },
    /* 分页器当前页展示的数据条数发生变化的回调函数 */
    handleSizeChange(size) {
      this.pageParams.size = size
      this.fetchEmployees()
    },
    /* 分页器当前页码发生变化的回调函数 */
    handleCurrentChange(page) {
      this.pageParams.page = page
      this.fetchEmployees()
    },
    /* 格式化聘用形式的回调函数 */
    formatEmployment(type) {
      // 枚举hireType对象
      return hireType[type] || '未知'
    },
    /* 点击删除员工按钮的回调函数 */
    async handleDeleteEmployees(employees) {
      const confirm = await this.$confirm(`删除${employees.username}, 是否继续?`, '提示', {type: 'warning'}).catch(error => error)
      if (confirm === 'cancel') return
      try {
        const message = await this.$store.dispatch('employeesStore/deleteEmployees', employees.id)
        this.$message.success(message)
        if (this.employeesList.length <= 1 && this.pageParams.page > 1) this.pageParams.page--
        this.fetchEmployees()
      } catch (error) {
        this.$message.error(error.message)
      }
    },
    /* 点击查看员工按钮的回调函数 */
    handleShowEmployees(employees) {
      // 携带params参数员工的ID，路由跳转到详情页
      this.$router.push({name: 'detail', params: {id: employees.id}})
    },
    /* 点击新增员工按钮的回调函数 */
    handleAddEmployee() {
      this.showEmpDialog = true
    },
    /* 添加员工对话框子组件添加员工成功的自定义事件 */
    addEmpSuccess() {
      this.showEmpDialog = false
      if (this.total % this.pageParams.size === 0) this.total++
      this.pageParams.page = Math.ceil(this.total / this.pageParams.size)
      this.fetchEmployees()
    },
    /* 点击导入excel按钮的回调函数 */
    importExcel() {
      this.showUploadDialog = true
    },
    /* 导入excel员工对话框组件的自定义事件 */
    importSuccess() {
      this.showUploadDialog = false
      this.fetchEmployees()
    },
    /* 点击导出excel按钮的回调函数 */
    async exportExcel() {
      const confirm = await this.$confirm('导出excel, 是否继续?', '提示', {type: 'warning'}).catch(error => error)
      if (confirm === "cancel") return
      // 默认拿到数组第一个对象的键(属性名)
      const header = Object.keys(this.employeesList[0])
      // 将员工列表转换为二维数组
      const data = this.employeesList.map(item => Object.values({...item, staffPhoto: item.staffPhoto ? item.staffPhoto : 'null', enableState: item.enableState === '1' ? '启用账号' : '禁用账户', formOfEmployment: formatEmployment(item.formOfEmployment)}))
      //
      const excel = await import('@/vendor/exportExcel')
      excel.export_json_to_excel({
        header, // 表头（数组格式）
        data, // 数据（二维数组）[['陶品奇', 'web前端']]
        filename: '员工表格', // 导出的文件名称
        autoWidth: true, // 是否自适应宽度
        bookType: 'xlsx' // 文件后缀名
      })
    },
    /* 点击分配角色按钮的回调函数 */
    async handleAssignRoles(employees) {
      // 使用ref获取子组件的实例调用子组件的fetchRoleList()发送请求获取所有角色列表
      await this.$refs.roleDialog.fetchRoleList()
      // 使用ref获取子组件的实例调用子组件的findRoleIds(员工的ID)发送请求获取当前员工的角色ID数组
      await this.$refs.roleDialog.findRoleIds(employees.id)
      // 打开对话框
      this.showRoleDialog = true
    }
  },
  computed: {
    /* 使用mapGetters将employeesStore模块下的getters映射为组件实例的属性 */
    ...mapGetters('employeesStore', ['employeesList']),
    /* 总共的数据条数 */
    total: {
      get() {
        return this.$store.getters["employeesStore/total"]
      },
      set(newValue) {
        this.$store.commit('employeesStore/addTotal', newValue)
      }
    },
    /* 提示信息 */
    title() {
      return `总共${this.total}位员工`
    }
  },
  mounted() {
    /* 组件挂载完毕调用fetchEmployees()函数派发action获取员工列表 */
    this.fetchEmployees()
  }

}
</script>

<template>
  <div class="employees">
    <el-card>
      <page-tools :title="title">
        <el-button type="danger" icon="el-icon-upload2" @click="exportExcel" v-per="'export'">导出excel</el-button>
        <el-button type="success" icon="el-icon-download" @click="importExcel" v-per="'import'">导入excel</el-button>
        <el-button type="primary" icon="el-icon-plus" @click="handleAddEmployee">新增员工</el-button>
      </page-tools>
    </el-card>
    <el-card>
      <el-table border stripe :data="employeesList">
        <el-table-column type="index" label="序号" align="center" width="100px"></el-table-column>
        <el-table-column prop="username" label="姓名" align="center" width="150px"></el-table-column>
        <el-table-column label="头像" align="center" width="150px">
          <template #default="{row}">
            <img :src="row.staffPhoto" v-if="row.staffPhoto">
            <avatar v-else :value="row.username"></avatar>
          </template>
        </el-table-column>
        <el-table-column prop="mobile" label="手机号" align="center"></el-table-column>
        <el-table-column prop="workNumber" label="工号" align="center" width="120px" sortable></el-table-column>
        <el-table-column label="聘用形式" align="center" width="150px">
          <template #default="{row}">
            <el-tag type="info" effect="dark">{{ formatEmployment(row.formOfEmployment) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="departmentName" label="所属部门" align="center" width="120px"></el-table-column>
        <el-table-column prop="timeOfEntry" label="入职时间" align="center" width="200px" sortable>
          <template #default="{row}">
            <span>{{ formatData(row.timeOfEntry) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="转正时间" align="center" width="200px" sortable>
          <template #default="{row}">
            <span>
              {{ formatData(row.correctionTime) }}
            </span>
          </template>
        </el-table-column>
        <el-table-column label="账号状态" align="center" width="220px">
          <template #default="{row}">
            <el-switch v-model="row.enableState" active-value="1" inactive-value="0"></el-switch>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center">
          <template #default="{row}">
            <el-button type="primary" icon="el-icon-view" @click="handleShowEmployees(row)">查看员工</el-button>
            <el-button type="success" icon="el-icon-position" @click="handleAssignRoles(row)">分配角色</el-button>
            <el-button type="danger" icon="el-icon-delete" @click="handleDeleteEmployees(row)">删除员工</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageParams.page" :page-sizes="[10, 20, 30, 40]" :page-size="pageParams.size" layout="total, sizes, prev, pager, next, jumper" :total="total" background></el-pagination>
    </el-card>
    <!--添加员工的对话框组件-->
    <emp-form-dialog title="新增员工" :show-emp-dialog.sync="showEmpDialog" :close-on-click-modal="false" append-to-body :page-params="pageParams" @addEmpSuccess="addEmpSuccess"></emp-form-dialog>
    <!--导入excel的对话框组件-->
    <upload-excel-dialog title="导入员工" :show-upload-dialog.sync="showUploadDialog" :close-on-click-modal="false" append-to-body @importSuccess="importSuccess"></upload-excel-dialog>
    <!--角色的对话框-->
    <role-dialog :show-role-dialog.sync="showRoleDialog" ref="roleDialog" append-to-body></role-dialog>
  </div>
</template>

<style scoped lang="scss">
.employees {
  .el-card {
    margin: 10px 0;

    img {
      width: 50px;
    }
  }

  .el-table {
    margin-bottom: 10px;
  }

  .el-pagination {
    text-align: center;
  }

  img {
    width: 50px;
    height: 50px;
    border-radius: 100%;
    object-fit: cover;
  }
}
</style>
